﻿using PmSoft.Core;
using PmSoft.Core.Domain.Entities;
using PmSoft.Data.Abstractions.Attributes;
using System.Reflection;

namespace PmSoft.Data.Abstractions.Events;

/// <summary>
/// 实体更新事件参数
/// </summary>
public class EntityUpdatedEventArgs : EntityEventArgs
{
	/// <summary>
	/// 更新前的实体
	/// </summary>
	public IEntity OldEntity { get; }

	/// <summary>
	/// 更新后的实体
	/// </summary>
	public IEntity NewEntity { get; }

	/// <summary>
	/// 变更的属性列表
	/// </summary>
	public List<EntityPropertyChangeInfo> ChangedProperties { get; }
	/// <summary>
	/// 审计属性
	/// </summary>
	public AuditableAttribute AuditableAttribute { get; set; }

	public EntityUpdatedEventArgs(IApplicationContext applicationContext, IEntity oldEntity, IEntity newEntity, AuditableAttribute auditableAttribute)
		: base(applicationContext, oldEntity)
	{
		OldEntity = oldEntity ?? throw new ArgumentNullException(nameof(oldEntity));
		NewEntity = newEntity ?? throw new ArgumentNullException(nameof(newEntity));
		AuditableAttribute = auditableAttribute ?? throw new ArgumentNullException(nameof(auditableAttribute));
		// 比较属性并记录变更
		ChangedProperties = CompareProperties(oldEntity, newEntity);
	}

	/// <summary>
	/// 比较两个实体的属性，返回变更列表
	/// </summary>
	private List<EntityPropertyChangeInfo> CompareProperties(IEntity oldEntity, IEntity newEntity)
	{
		var changes = new List<EntityPropertyChangeInfo>();
		var properties = oldEntity.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

		foreach (var property in properties)
		{
			// 忽略只读属性
			if (!property.CanRead || !property.CanWrite)
				continue;

			var oldValue = property.GetValue(oldEntity);
			var newValue = property.GetValue(newEntity);

			// 如果值不相等，记录变更
			if (!Equals(oldValue, newValue))
			{
				changes.Add(new EntityPropertyChangeInfo(property.Name, oldValue, newValue));
			}
		}

		return changes;
	}
}
